﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Remoting.Messaging;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Communication.Lib;
using Communication.Lib.Communication;
using Communication.Lib.Mode;
using Communication.Lib.Protocol;

namespace Communication.Test
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            testTcp();
        }

        #region TCP test

        private static void testTcp()
        {
            Console.WriteLine("input s/c");
            var input = Console.ReadLine();
            if (input.Equals("s", StringComparison.CurrentCultureIgnoreCase))
            {
                Console.WriteLine("server start");
                var server = new TCPCommunicate<BIInfo>("127.0.0.1", 0, 9968, ProtocolBI.Instance, true);
                server.RecvCallBack += ServerRecvCallBack;
                server.Start();
            }
            else
            {
                Console.WriteLine("client start");
                var client = new TCPCommunicate<BIInfo>("127.0.0.1", 9968, 0, ProtocolBI.Instance);
                client.RecvHandler += ClientRecvHandler; ;
                client.Start();
                var read = Console.ReadLine().Trim();
                while (!string.IsNullOrEmpty(read))
                {
                    var info = new BIInfo();
                    switch (read)
                    {
                        case "1":
                            info.Flag = BiFlag.Connection;
                            info.Data = Guid.NewGuid().ToString();
                            break;

                        case "3":
                            info.Flag = BiFlag.Close;
                            break;

                        case "4":
                            info.Flag = BiFlag.DevStatus;
                            info.Data = 0x01.ToString();
                            break;

                        case "5":
                            info.Flag = BiFlag.BagCount;
                            info.Data = 590.ToString();
                            break;

                        case "6":
                            info.Flag = BiFlag.Alarm;
                            info.Data = "000001_20200115_155250_00000178";
                            break;

                        default:
                            info.Flag = BiFlag.Beat;
                            break;
                    }
                    client.SendData(info);
                    Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} client send:" + ProtocolBI.Instance.EncodeBytes(info).FormatAsHex());
                    read = Console.ReadLine().Trim();
                }
            }
            Console.ReadLine();
        }

        private static void ClientRecvHandler(BIInfo obj)
        {
            Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} client recv:" + ProtocolBI.Instance.EncodeBytes(obj).FormatAsHex());
        }

        private static void ServerRecvCallBack(System.Net.Sockets.Socket sc, BIInfo info)
        {
            Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} server recv:" + info.Data);
            var echo = new BIInfo();
            echo.Flag = info.Flag;
            if (sc.Connected)
            {
                var data = ProtocolBI.Instance.EncodeBytes(echo);
                sc.Send(data);
                Console.WriteLine($"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")} server echo:" + data.FormatAsHex());
            }
        }

        private static void Server_RecvHandler1(DemoInfo obj)
        {
            Console.WriteLine($" client recvdata {obj.ToJson()}");
        }

        private static void Server_RecvCallBack(System.Net.Sockets.Socket sc, DemoInfo info)
        {
            Console.WriteLine($" Server recvdata {info.ToJson()}");
            info.Data += 10;
            info.Valid = 3;
            var data = DemoProtocol.Instance.EncodeBytes(info);
            sc.Send(data);
        }

        #endregion TCP test

        #region UDP test

        private static void testUdp()
        {
            string groupip = "224.100.0.11";

            var server = new UDPCommunicate<DemoInfo>(groupip, 9216, 9215, DemoProtocol.Instance, true) { Name = "server" };

            server.RecvHandler += Server_RecvHandler;
            server.Start();

            var client1 = new UDPCommunicate<DemoInfo>(groupip, 9215, 9216, DemoProtocol.Instance, true) { Name = "client1" };
            client1.RecvHandler += Client1_RecvHandler;
            var client2 = new UDPCommunicate<DemoInfo>(groupip, 9215, 9216, DemoProtocol.Instance, true) { Name = "client2" };
            client2.RecvHandler += Client2_RecvHandler;
            var client3 = new UDPCommunicate<DemoInfo>(groupip, 9215, 9216, DemoProtocol.Instance, true) { Name = "client3" };
            client3.RecvHandler += Client3_RecvHandler;

            IList<UDPCommunicate<DemoInfo>> list = new List<UDPCommunicate<DemoInfo>>() { client1, client2, client3 };

            int i = 0;
            Random r = new Random();
            while (i < 10)
            {
                i++;
                foreach (var communicate in list)
                {
                    var d = new DemoInfo() { Data = (float)(r.NextDouble() * i * 125), Valid = 2 };
                    communicate.SendData(d);
                    Console.WriteLine($"[send] {communicate.Name} :{d.ToJson()}");
                }

                Console.WriteLine(i);
                Thread.Sleep(500);
            }

            foreach (var communicate in list)
            {
                communicate.Start();
            }

            while (i < 20)
            {
                i++;

                var d = new DemoInfo() { Data = (float)(r.NextDouble() * i * 125), Valid = 2 };
                server.SendData(d);
                Console.WriteLine($"[send] {server.Name} :{d.ToJson()}");

                Console.WriteLine(i);
                Thread.Sleep(500);
            }

            Console.ReadLine();
        }

        private static void Client1_RecvHandler(DemoInfo obj)
        {
            Console.WriteLine($"[recv] Client1 {obj.ToJson()}");
        }

        private static void Client2_RecvHandler(DemoInfo obj)
        {
            Console.WriteLine($"[recv] Client2 {obj.ToJson()}");
        }

        private static void Client3_RecvHandler(DemoInfo obj)
        {
            Console.WriteLine($"[recv] Client3 {obj.ToJson()}");
        }

        private static void Server_RecvHandler(DemoInfo obj)
        {
            Console.WriteLine($"[recv] server {obj.ToJson()}");
        }

        #endregion UDP test
    }
}